
#########################################################################

# Copyright (C) Flavio Piccinelli 2012 <flavio.picci@gmail.com>

#########################################################################

# Aria.rb
# This file is part of "AriaAperta".

# AriaAperta is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# AriaAperta is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with AriaAperta.  If not, see <http://www.gnu.org/licenses/>.

#########################################################################
#########################################################################


#########################################################################
# Environment Configuration
#########################################################################
ONE_LOCATION=ENV["ONE_LOCATION"]

if !ONE_LOCATION
		RUBY_LIB_LOCATION="/usr/lib/one/ruby"
else
		RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
end

$: << RUBY_LIB_LOCATION

# OpenNebula credentials
# CREDENTIALS = "oneadmin:oneadmin"
#useradmin
USER = "piccinel"
CREDENTIALS = "#{USER}:piccinel"
# XML_RPC endpoint where OpenNebula is listening
ENDPOINT    = "http://localhost:2633/RPC2"
#########################################################################
# Required libraries
#########################################################################
require "OpenNebula"
require "lib/const"
require "lib/Utils"
#########################################################################
#########################################################################

module Aria

	def get_pool(pool_type, credentials)

		if credentials.nil?
			credentials = CREDENTIALS
		end

		oneuser = OpenNebula::Client.new(credentials, ENDPOINT)

		case pool_type
		when HOSTS
			pool = OpenNebula::HostPool.new(oneuser)
		when IMGS
			pool = OpenNebula::ImagePool.new(oneuser)
		when USERS
			pool = OpenNebula::UserPool.new(oneuser)
		when VMS
			pool = OpenNebula::VirtualMachinePool.new(oneuser)
		end

		return pool
	end

	def start_vm(host_id, img, credentials, semaphore)

		vm_pool = get_pool(VMS, credentials)
		
		vm_id = -1
		vm = vm_pool.factory(OpenNebula::VirtualMachine.build_xml)

		#mutex init
		semaphore.synchronize {
			vm_tmpl = Utils::create_tmpl(img, credentials)
# 			puts "tmpl created"
# 			puts vm_tmpl
			rc = vm.allocate(vm_tmpl)
			if OpenNebula.is_error?(rc)
				puts rc.message
				return rc.message
			end
		
			vm_id = vm.id
			vm_pool = get_pool(VMS, nil)
			vm_pool.info(OpenNebula::Pool::INFO_ALL, vm_id, vm_id)
			vm_pool.each do |vm|
				rc = vm.deploy(host_id)
				if OpenNebula.is_error?(rc)
					puts rc.message
					return rc.message
				end
			end
		}
		#mutex exit
		puts "vm #{vm_id} deployed"

		return vm_id
	end

	def shut_vm(users, vm_ids)
		vms_shut = 0
		
		if vm_ids.nil?
			vm_pool = get_pool(VMS, nil)
			vm_pool.info_all
			vm_pool.each do |vm|
				if users.include?(vm["UNAME"])
					vm.cancel
					vms_shut += 1
				end
			end
		else
			users.each do |user|
				puts user
				vm_pool = get_pool(VMS, user)
				vm_pool.info_mine
				vm_pool.each do |vm|
					if vm_ids.include?(vm.id)
						vm.cancel
						vms_shut += 1
					end
				end
			end
		end
		return vms_shut
	end

	def shut_all_err()
		vm_pool = get_pool(VMS, nil)
		vm_pool.info_all
		vm_pool.each do |vm|
			if vm.state == FAILED || vm.lcm_state > SHUTDOWN
				vm.finalize
			end
		end
	end

	def get_imgs(req)

		im_pool = get_pool(IMGS, nil)

		imgs_arr = Array.new

		im_pool.info_mine
		im_pool.each do |img|
			state = img.state
			name = img.name
			if (req ^ (name == "voip")) && (state < 3)
				desc = img["TEMPLATE/DESCRIPTION"]
				imgs_arr << [img.id, name, desc, img.type.to_i]
# 				puts "#{desc} is a #{desc.class}"
# 				puts "img type: #{img.type}"
			end
		end

		return imgs_arr
	end

	def avail_hosts()

		ht_arr = Array.new

		ht_pool = get_pool(HOSTS, nil)
		ht_pool.info
		ht_pool.each do |host|
			if host.state < ERROR
				puts host.name
				prest = `ssh #{USER}@#{host.name} one/scripts/hostCheck.rb`.chomp.split("+")
				if prest.length == 2
					cpu = prest[0].to_f
					mem = prest[1].to_i
# 					puts prest
					if (mem > 64)
						ht_arr << [host.name, cpu, host.id]
					end
				end
			end
		end

		return ht_arr
	end

end
